package edu.mercer.employmentcalculator;

import java.lang.IllegalArgumentException;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.content.Context;
import java.util.Hashtable;

public class ZipColiGetter
{
	private Context _context;

	Hashtable<Integer, String> zipToMha = new Hashtable<Integer, String>();
	Hashtable<String, Double> mhaToColi = new Hashtable<String, Double>();
	boolean _preload;
	
	public ZipColiGetter(Context context, boolean preload)
	{
		if (context == null)
			throw new IllegalArgumentException("context cannot be null");
		
		this._context = context;
		this._preload = preload;
		
		if (preload)
			LoadHashtables();
	}
	
	private void LoadHashtables()
	{
		PopulateZipToMha();
		PopulateMhaToColi();
	}
	
	private void PopulateZipToMha()
	{
		InputStream stream = this._context.getResources().openRawResource(R.raw.sorted_zipmha13);
		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
		String line = null;
	    try
	    {
	        while ((line = reader.readLine()) != null)
	        {
	            String[] tokens = line.split(" ");
	            Integer zip = Integer.parseInt(tokens[0]);
	            zipToMha.put(zip, tokens[1]);
	        }
	    }
	    catch (IOException e) { }
	    finally
	    {
	    	try
	    	{
		        stream.close();	    		
	    	}
	    	catch (IOException e) { }
	    }
	}
	
	private void PopulateMhaToColi()
	{
		InputStream stream = this._context.getResources().openRawResource(R.raw.sorted_mhacoli13);
		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
		String line = null;
	    try
	    {
	        while ((line = reader.readLine()) != null)
	        {
	            String[] tokens = line.split(" ");
	            Double coli = Double.parseDouble(tokens[1]);
	            mhaToColi.put(tokens[0], coli);
	        }
	    }
	    catch (IOException e) { }
	    finally
	    {
	    	try
	    	{
		        stream.close();	    		
	    	}
	    	catch (IOException e) { }
	    }
	}
	
	public double GetColi(String zipString)
	{
		int zip = Integer.parseInt(zipString);
		return GetColi(zip);
	}
	
	public double GetColi(int zipCode)
	{
		if (this._preload)
			return GetColiPreloaded(zipCode);
		else
			return GetColiPassive(zipCode);
	}
	
	private double GetColiPreloaded(int zipCode)
	{
		if (zipToMha.containsKey(zipCode))
		{
			String mha = zipToMha.get(zipCode);
			if (mhaToColi.containsKey(mha))
				return mhaToColi.get(mha);
			else
				throw new IllegalArgumentException("mha not found");
		}
		else
			throw new IllegalArgumentException("zip not found");
	}
	
	private double GetColiPassive(int zipCode)
	{
		// search text file for line with zip
		String line = getZipLine(zipCode);
		
		// get MHA from that line
		String mha = line.substring(line.indexOf(' ') + 1, 5); // space delimited
		
		// search text file for line with mha
		String mhaLine = getMhaLine(mha);
		
		// get COLI from that line
		String coliString = mhaLine.substring(mhaLine.indexOf(' ') + 1, 4); // space delimited
		
		// parse COLI string into double
		double coli = Double.parseDouble(coliString);
		
		return coli;
	}
	
	private String getZipLine(int zipCode)
	{
		String zipString = Integer.toString(zipCode);
		while (zipString.length() < 5)
			zipString = '0' + zipString;
		
		// search sorted_zipmha13 for line with zipCode and return that line
		InputStream stream = this._context.getResources().openRawResource(R.raw.sorted_zipmha13);
		try
		{
			return ReturnLineWithSpecifiedText(stream, zipString);
		}
		catch (IllegalArgumentException e)
		{
			// if line not found, throw exception
			throw new IllegalArgumentException("zip not found");
		}
	}
	
	private String ReturnLineWithSpecifiedText(InputStream stream, String searchString)
	{
		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));

	    String line = null;
	    try
	    {
	        while ((line = reader.readLine()) != null)
	        {
	            if (line.contains(searchString))
	            	return line;
	        }
	    }
	    catch (IOException e) { }
	    finally
	    {
	    	try
	    	{
		        stream.close();	    		
	    	}
	    	catch (IOException e) { }
	    }
	    
	    throw new IllegalArgumentException("search string not found");
	}
	
	private String getMhaLine(String mha)
	{
		InputStream stream = this._context.getResources().openRawResource(R.raw.sorted_mhacoli13);
		try
		{
			return ReturnLineWithSpecifiedText(stream, mha);
		}
		catch (IllegalArgumentException e)
		{
			// if line not found, throw exception
			throw new IllegalArgumentException("mha not found");
		}
	}
}
